﻿#ifndef SOLVERS_PRECONDITIONERS_LDUMGPRECOND_HPP
#define SOLVERS_PRECONDITIONERS_LDUMGPRECOND_HPP
/*! \file MGPrecond.hpp
 *  \author Zhao Chengpeng (chengpeng_zhao@foxmail.com)
 *  \date 2022-10-24
 *   \modified 2023-08-04
 *  \brief multigrid preconditioner
 */

#include "unapMatrix.hpp"
#include "unapMultigrid.hpp"
#include "unapPreconditioner.hpp"

namespace UNAP {

template <typename Cmpt>
class MGPrecond : public Preconditioner<Cmpt> {
 private:
  /// \brief the reciprocal diagonal
  Vector<Cmpt> rD_;

  /// Number of cycles to perform
  label nCycles_;

  MGSolver<Cmpt> *MGpreond_;

 public:
  /// \brief constructor
  /// \param A matrix input
  MGPrecond(const Matrix<Cmpt> &A, MGSolver<Cmpt> *MG);

  /// \brief destructor
  virtual ~MGPrecond() {}

  /// \brief return wA the preconditioned form of residual rA
  /// \param w resulting vector, preconditioned by rA
  /// \param r Preconditioner vector
  virtual void precondition(Vector<Cmpt> &w, const Vector<Cmpt> &r) const;

  /// \brief return the reciprocal diagonal
  virtual const Vector<Cmpt> &rD() const { return rD_; }

  void SET_nCycles(label n) { nCycles_ = n; }
};

}  // namespace UNAP

#endif /* end of include guard: SOLVERS_PRECONDITIONERS_LDUMGPRECOND_HPP */
